package org.light.oracle.core;

import java.util.Set;
import java.util.TreeSet;

import org.light.complexverb.AddUploadDomainField;
import org.light.complexverb.DomainFieldVerb;
import org.light.complexverb.UpdateUploadDomainField;
import org.light.core.PrismInterface;
import org.light.core.SpringMVCController;
import org.light.core.Verb;
import org.light.domain.Dao;
import org.light.domain.DaoImpl;
import org.light.domain.Domain;
import org.light.domain.Field;
import org.light.domain.ManyToMany;
import org.light.domain.Method;
import org.light.domain.Prism;
import org.light.domain.Service;
import org.light.domain.ServiceImpl;
import org.light.domain.Type;
import org.light.domain.ValidateInfo;
import org.light.exception.ValidateException;
import org.light.generator.NamedUtilMethodGenerator;
import org.light.layouts.EasyUIMtmPI;
import org.light.layouts.OracleEasyUIGridPagePI;
import org.light.limitedverb.DaoOnlyVerb;
import org.light.limitedverb.NoControllerVerb;
import org.light.oracle.generator.MybatisOracleDaoXmlDecorator;
import org.light.oracle.limitedverb.CountActiveRecords;
import org.light.oracle.limitedverb.CountSearchByFieldsRecords;
import org.light.oracle.oracleverb.Activate;
import org.light.oracle.oracleverb.ActivateAll;
import org.light.oracle.oracleverb.Add;
import org.light.oracle.oracleverb.CloneAll;
import org.light.oracle.oracleverb.Delete;
import org.light.oracle.oracleverb.DeleteAll;
import org.light.oracle.oracleverb.Export;
import org.light.oracle.oracleverb.ExportPDF;
import org.light.oracle.oracleverb.FilterExcel;
import org.light.oracle.oracleverb.FilterPDF;
import org.light.oracle.oracleverb.FindById;
import org.light.oracle.oracleverb.FindByName;
import org.light.oracle.oracleverb.ListActive;
import org.light.oracle.oracleverb.ListAll;
import org.light.oracle.oracleverb.SearchByFields;
import org.light.oracle.oracleverb.SearchByFieldsByPage;
import org.light.oracle.oracleverb.SoftDelete;
import org.light.oracle.oracleverb.SoftDeleteAll;
import org.light.oracle.oracleverb.Toggle;
import org.light.oracle.oracleverb.ToggleOne;
import org.light.oracle.oracleverb.Update;
import org.light.utils.StringUtil;
import org.light.verb.CheckAccess;
import org.light.verb.Clone;
import org.light.verb.ExportPPT;
import org.light.verb.ExportWord;
import org.light.verb.FilterPPT;
import org.light.verb.FilterWord;
import org.light.verb.FindFullInfoById;
import org.light.verb.SearchIndexedNamesByShortName;

public class OraclePrism extends Prism{
	protected MybatisOracleDaoXmlDecorator mybatisOracleDaoXmlDecorator = new MybatisOracleDaoXmlDecorator();

	public OraclePrism() {
		super();
	}
	
	public void removeVerb(Verb verb) throws Exception{
		if (verb != null) {
			this.verbs.remove(verb);
			service.removeMethod(verb.generateServiceMethodDefinition());
			serviceimpl.removeMethod(verb.generateServiceImplMethod());
			dao.removeMethod(verb.generateDaoMethodDefinition());
			daoimpl.removeMethod(verb.generateDaoImplMethod());
			controller.removeMethod(verb.generateControllerMethod());
			getMybatisOracleDaoXmlDecorator().removeDaoXmlMethod(verb.generateDaoImplMethod());
		}
	}

	@Override
	public void generatePrismFiles(Boolean ignoreWarning,Boolean genUi,Boolean genController,Boolean genService,Boolean genServiceImpl,Boolean genDao,Boolean genDaoImpl) throws ValidateException {
		ValidateInfo info = this.validate(ignoreWarning);
		if (info.success(ignoreWarning) == false) {
			ValidateException e = new ValidateException(info);
			throw e;
		}
		try {
			String projectFolderPath = folderPath.replace('\\', '/');
			String srcfolderPath = projectFolderPath;
			if (this.packageToken != null && !"".equals(this.packageToken)){
				srcfolderPath = folderPath + "src/main/java/" + packagetokenToFolder(this.packageToken);

				writeToFile(srcfolderPath +packagetokenToFolder(this.domain.getDomainSuffix())  +this.getDomain().getCapFirstDomainNameWithSuffix()+ ".java",
						this.getDomain().generateClassString());
			
				if (genDao&&this.getDao() != null) {
					writeToFile(
							srcfolderPath + packagetokenToFolder(this.domain.getDaoSuffix()) + StringUtil.capFirst(this.getDomain().getStandardName()) + "Dao.java",
							this.getDao().generateDaoString());
				}
	
				if (genDaoImpl&&this.getDaoImpl() != null) {
					writeToFile(
							folderPath + "src/main/resources/mapper/" + StringUtil.capFirst(this.getDomain().getStandardName()) + "Dao.xml",
							this.mybatisOracleDaoXmlDecorator.generateMybatisDaoXmlFileStr());
				}
	
				if (genService&&this.getService() != null) {
					writeToFile(srcfolderPath +  packagetokenToFolder(this.domain.getServiceSuffix())  + StringUtil.capFirst(this.getDomain().getStandardName())
							+ "Service.java", this.getService().generateServiceString());
				}
	
				if (genServiceImpl&&this.getServiceImpl() != null) {
					writeToFile(srcfolderPath + packagetokenToFolder(this.domain.getServiceimplSuffix()) + StringUtil.capFirst(this.getDomain().getStandardName())
							+ "ServiceImpl.java", this.getServiceImpl().generateServiceImplString());
				}
	
				if (genController&&this.controller != null) {
					writeToFile(srcfolderPath +  packagetokenToFolder(this.domain.getControllerSuffix())  + StringUtil.capFirst(this.domain.getCapFirstDomainName())
							+ this.domain.getControllerNamingSuffix()+".java", this.controller.generateControllerString());
				}
	
				if (genUi) {
					for (PrismInterface page : this.getPages()) {
						page.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
						page.setTechnicalStack(this.technicalStack);
						page.generatePIFiles(projectFolderPath);
					}
					
					for (ManyToMany mtm : this.manyToManies) {
						EasyUIMtmPI mpage = mtm.getEuPI();
						mpage.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
						mpage.setTechnicalStack(this.technicalStack);
						mpage.generatePIFiles(projectFolderPath);						
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void generateSMEUPrismFiles(Boolean ignoreWarning,Boolean genUi,Boolean genController,Boolean genService,Boolean genServiceImpl,Boolean genDao,Boolean genDaoImpl) throws ValidateException {
		ValidateInfo info = this.validate(ignoreWarning);
		if (info.success(ignoreWarning) == false) {
			ValidateException e = new ValidateException(info);
			throw e;
		}
		try {
			String projectFolderPath = folderPath.replace('\\', '/');
			String srcfolderPath = projectFolderPath;
			if (this.packageToken != null && !"".equals(this.packageToken)){
				srcfolderPath = folderPath + "src/" + packagetokenToFolder(this.packageToken);

				writeToFile(srcfolderPath + packagetokenToFolder(this.domain.getDomainSuffix())+StringUtil.capFirst(this.getDomain().getCapFirstDomainNameWithSuffix()) + ".java",
					this.getDomain().decorateCompareTo().generateClassString());
			
				if (genDao&&this.getDao() != null) {
					writeToFile(
							srcfolderPath + packagetokenToFolder(this.domain.getDaoSuffix()) + StringUtil.capFirst(this.getDomain().getStandardName()) + "Dao.java",
							this.getDao().generateDaoString());
				}
	
				if (genDaoImpl&&this.getDaoImpl() != null) {
					if (this.domain instanceof org.light.domain.Enum) {
						writeToFile(
								srcfolderPath + packagetokenToFolder(this.domain.getDaoimplSuffix()) + StringUtil.capFirst(this.getDomain().getStandardName()) + "DummyDaoImpl.java",
								this.getDummydaoimpl().generateDaoImplString());
					} else {
						writeToFile(
								srcfolderPath + packagetokenToFolder(this.domain.getDaoSuffix()) + StringUtil.capFirst(this.getDomain().getStandardName()) + "Dao.xml",
								this.mybatisOracleDaoXmlDecorator.generateMybatisDaoXmlFileStr());
					}
				}
	
				if (genService&&this.getService() != null) {
					writeToFile(srcfolderPath + packagetokenToFolder(this.domain.getServiceSuffix()) +StringUtil.capFirst(this.getDomain().getStandardName())
							+ "Service.java", this.getService().generateServiceString());
				}
	
				if (genServiceImpl&&this.getServiceImpl() != null) {
					writeToFile(srcfolderPath +packagetokenToFolder(this.domain.getServiceimplSuffix()) +StringUtil.capFirst(this.getDomain().getStandardName())
							+ "ServiceImpl.java", this.getServiceImpl().generateServiceImplString());
				}
	
				if (genController&&this.controller != null) {
					writeToFile(srcfolderPath +packagetokenToFolder(this.domain.getControllerSuffix()) +StringUtil.capFirst(this.domain.getCapFirstDomainName())
							+ this.domain.getControllerNamingSuffix()+".java", this.controller.generateControllerString());
				}

				if (genUi) {
					for (PrismInterface page : this.getPages()) {
						page.setTechnicalStack(this.technicalStack);
						page.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
						page.generatePIFiles(projectFolderPath);
					}
					
					for (ManyToMany mtm : this.manyToManies) {
						EasyUIMtmPI mpage = mtm.getEuPI();
						mpage.setTechnicalStack(this.technicalStack);
						mpage.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
						mpage.generatePIFiles(projectFolderPath);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void generatePrismFromDomain(Boolean ignoreWarning) throws ValidateException, Exception {
		if (this.domain != null) {
			if (this.getPackageToken() != null) {
				this.domain.setPackageToken(packageToken);
			}
			
			this.domain.decorateCompareTo();

			this.dao = new Dao();
			this.dao.setDomain(this.domain);
			this.dao.setPackageToken(this.domain.getPackageToken());
			this.daoimpl = new DaoImpl();
			this.daoimpl.setPackageToken(this.domain.getPackageToken());
			this.daoimpl.setDomain(this.domain);
			this.daoimpl.setDao(this.dao);

			this.service = new Service();
			this.service.setDomain(this.domain);
			this.service.setPackageToken(this.domain.getPackageToken());
			this.serviceimpl = new ServiceImpl(this.domain);
			this.serviceimpl.setPackageToken(this.domain.getPackageToken());
			this.serviceimpl.getDao().addAnnotation("Autowired");
			Method daoSetter = NamedUtilMethodGenerator.generateSetter("dao",
					new Type(this.domain.getCapFirstDomainName() + "Dao"));
			this.serviceimpl.addMethod(daoSetter);
			this.serviceimpl.addClassImports("org.springframework.beans.factory.annotation.Autowired");
			this.serviceimpl.setDomain(this.domain);
			this.serviceimpl.setService(this.service);

			Verb listAll = new ListAll(this.domain);			
			Verb update = this.domain.hasDomainId() ?new Update(this.domain):null;
			Verb delete = this.domain.hasDomainId() ?new Delete(this.domain):null;
			Verb add = this.domain.hasDomainId() ?new Add(this.domain):null;
			Verb softdelete = this.domain.hasDomainId() && this.domain.hasActiveField() ?new SoftDelete(this.domain):null;
			Verb findbyid = this.domain.hasDomainId() ? new FindById(this.domain):null;
			Verb findbyname = this.domain.hasDomainName() ? new FindByName(this.domain):null;
			Verb listactive = this.domain.hasActiveField()?new ListActive(this.domain):null;
			Verb deleteAll = this.domain.hasDomainId() ?new DeleteAll(this.domain):null;
			Verb softDeleteAll = this.domain.hasDomainId() && this.domain.hasActiveField() ?new SoftDeleteAll(this.domain):null;
			Verb toggle = this.domain.hasDomainId() && this.domain.hasActiveField() ?new Toggle(this.domain):null;
			Verb toggleOne = this.domain.hasDomainId() && this.domain.hasActiveField() ?new ToggleOne(this.domain):null;
			Verb searchByFieldsByPage = new SearchByFieldsByPage(this.domain);
			Verb activate = this.domain.hasDomainId() && this.domain.hasActiveField() ?new Activate(this.domain):null;
			Verb activateAll = this.domain.hasDomainId() && this.domain.hasActiveField() ?new ActivateAll(this.domain):null;
			Verb export = new Export(this.domain);
			Verb exportPDF = new ExportPDF(this.domain);
			Verb exportWord = new ExportWord(this.domain);
			Verb exportPPT = new ExportPPT(this.domain);
			Verb searchByFields = new SearchByFields(this.domain);
			Verb filterExcel = new FilterExcel(this.domain);
			Verb filterPDF = new FilterPDF(this.domain);
			Verb filterWord = new FilterWord(this.domain);
			Verb filterPPT = new FilterPPT(this.domain);
			Verb clone	= this.domain.hasDomainId() ?new Clone(this.domain):null;
			Verb findFullInfoById = this.domain.hasDomainId() ?new FindFullInfoById(this.domain):null;
			Verb searchIndexedNamesByShortName = this.domain.hasDomainId() ?new SearchIndexedNamesByShortName(this.domain):null;
			Verb cloneAll = this.domain.hasDomainId()  ?new CloneAll(this.domain):null;
			Verb checkAcces = new CheckAccess(this.domain);

			CountSearchByFieldsRecords countSearch = new CountSearchByFieldsRecords(this.domain);
			CountActiveRecords countActiveRecords = this.domain.hasDomainId() && this.domain.hasActiveField() ? new CountActiveRecords(this.domain):null;

			for (Field f:this.domain.getPlainFields()) {
				if (f.getFieldType().equalsIgnoreCase("image")) {
					domianFieldVerbs.add(new AddUploadDomainField(this.domain,f));
					domianFieldVerbs.add(new UpdateUploadDomainField(this.domain,f));
				}
			}
			
			this.addVerb(listAll);
			this.addVerb(update);
			this.addVerb(delete);
			this.addVerb(add);
			this.addVerb(softdelete);
			this.addVerb(findbyid);
			this.addVerb(findbyname);
			this.addVerb(listactive);
			this.addVerb(deleteAll);
			this.addVerb(softDeleteAll);
			this.addVerb(toggle);
			this.addVerb(toggleOne);
			this.addVerb(searchByFieldsByPage);
			this.addVerb(activate);
			this.addVerb(activateAll);
			this.addVerb(export);
			this.addVerb(exportPDF);
			this.addVerb(exportWord);
			this.addVerb(exportPPT);
			this.addVerb(searchByFields);
			this.addVerb(filterExcel);
			this.addVerb(filterPDF);
			this.addVerb(filterWord);
			this.addVerb(filterPPT);
			this.addVerb(clone);
			this.addVerb(findFullInfoById);
			this.addVerb(searchIndexedNamesByShortName);
			this.addVerb(cloneAll);
			this.addVerb(checkAcces);

			if (countSearch !=null) this.noControllerVerbs.add(countSearch);
			if (countActiveRecords !=null) this.noControllerVerbs.add(countActiveRecords);
			this.controller = new SpringMVCController(this.verbs, this.domain,ignoreWarning);
			this.controller.setPackageToken(this.packageToken);

			for (Verb v : this.verbs) {
				v.setDomain(domain);
				service.addMethod(v.generateServiceMethodDefinition());
				serviceimpl.addMethod(v.generateServiceImplMethod());
				dao.addMethod(v.generateDaoMethodDefinition());
				daoimpl.addMethod(v.generateDaoImplMethod());
				controller.addMethod(v.generateControllerMethod());
			}

			for (NoControllerVerb nVerb : this.noControllerVerbs) {
				nVerb.setDomain(domain);
				service.addMethod(nVerb.generateServiceMethodDefinition());
				serviceimpl.addMethod(nVerb.generateServiceImplMethod());
				dao.addMethod(nVerb.generateDaoMethodDefinition());
				daoimpl.addMethod(nVerb.generateDaoImplMethod());
			}

			for (DaoOnlyVerb oVerb : this.daoOnlyVerbs) {
				oVerb.setDomain(domain);
				dao.addMethod(oVerb.generateDaoMethodDefinition());
				daoimpl.addMethod(oVerb.generateDaoImplMethod());
			}
			
			for (DomainFieldVerb dfv:domianFieldVerbs) {
				this.controller.addMethod(dfv.generateControllerMethod());
			}

			this.mybatisOracleDaoXmlDecorator = new MybatisOracleDaoXmlDecorator();
			this.mybatisOracleDaoXmlDecorator.setDomain(this.getDomain());
			Set<Domain> resultMaps = new TreeSet<Domain>();
			resultMaps.add(this.domain);
			this.mybatisOracleDaoXmlDecorator.setResultMaps(resultMaps);
			Set<Method> daoimplMethods = new TreeSet<Method>();
			for (Verb vb : this.verbs) {
				if (vb!=null && vb.generateDaoImplMethod()!=null){
					daoimplMethods.add(vb.generateDaoImplMethod());
				}
			}
			for (DaoOnlyVerb dovb : this.daoOnlyVerbs) {
				if (dovb!=null && dovb.generateDaoImplMethod()!=null){
					daoimplMethods.add(dovb.generateDaoImplMethod());
				}
			}
			for (NoControllerVerb ncvb : this.noControllerVerbs) {
				if (ncvb!=null && ncvb.generateDaoImplMethod()!=null){
					daoimplMethods.add(ncvb.generateDaoImplMethod());
				}
			}
			this.mybatisOracleDaoXmlDecorator.setDaoXmlMethods(daoimplMethods);

			OracleEasyUIGridPagePI easyui = new OracleEasyUIGridPagePI(this.domain);
			easyui.setTechnicalStack(this.technicalStack);
			easyui.setTitles(this.title,this.subTitle, this.footer);
			this.addPage(easyui);

			if (this.domain.getManyToManies() != null && this.domain.getManyToManies().size() > 0) {
				this.setManyToManies(new TreeSet<>());
				for (ManyToMany mtm : this.domain.getManyToManies()) {
					String slaveName = mtm.getManyToManySalveName();
					String masterName = this.domain.getStandardName();
					if (setContainsDomain(this.projectDomains, masterName)
							&& setContainsDomain(this.projectDomains, slaveName)) {
						
						Domain myslave = (Domain)lookupDoaminInSet(this.projectDomains, slaveName).deepClone();
						if (!StringUtil.isBlank(mtm.getSlaveAlias())){
							myslave.setAlias(mtm.getSlaveAlias());
							myslave.setAliasLabel(mtm.getSlaveAliasLabel());
						}
						OracleManyToMany mymtm = new OracleManyToMany(lookupDoaminInSet(this.projectDomains, masterName),
								myslave,mtm.getMasterValue(),mtm.getValues());	
						mymtm.setSlaveAlias(myslave.getAlias());
						EasyUIMtmPI eumpt = mymtm.getEuPI();
						eumpt.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
						eumpt.setTechnicalStack(this.getTechnicalStack());
						mymtm.setEuPI(eumpt);
						this.manyToManies.add(mymtm);
					} else {
						ValidateInfo validateInfo = new ValidateInfo();
						validateInfo.addCompileError("棱柱" + this.getText() + "多对多设置有误。");
						ValidateException em = new ValidateException(validateInfo);
						throw em;
					}
				}
			}
			for (ManyToMany mtm : this.manyToManies) {
				OracleManyToMany omtm = (OracleManyToMany) mtm;
				omtm.setTitle(this.title);
				omtm.setSubTitle(this.subTitle);
				omtm.setFooter(this.footer);
				omtm.setCrossOrigin(this.crossOrigin);
				this.service.addMethod(omtm.getOracleAssign().generateServiceMethodDefinition());
				this.serviceimpl.addMethod(omtm.getOracleAssign().generateServiceImplMethod());
				this.dao.addMethod(omtm.getOracleAssign().generateDaoMethodDefinition());
				this.daoimpl.addMethod(omtm.getOracleAssign().generateDaoImplMethod());
				this.mybatisOracleDaoXmlDecorator.addDaoXmlMethod(omtm.getOracleAssign().generateDaoImplMethod());
				this.controller.addMethod(omtm.getOracleAssign().generateControllerMethod());

				this.service.addMethod(omtm.getOracleRevoke().generateServiceMethodDefinition());
				this.serviceimpl.addMethod(omtm.getOracleRevoke().generateServiceImplMethod());
				this.dao.addMethod(omtm.getOracleRevoke().generateDaoMethodDefinition());
				this.daoimpl.addMethod(omtm.getOracleRevoke().generateDaoImplMethod());
				this.mybatisOracleDaoXmlDecorator.addDaoXmlMethod(omtm.getOracleRevoke().generateDaoImplMethod());
				this.controller.addMethod(omtm.getOracleRevoke().generateControllerMethod());

				this.service.addMethod(omtm.getOracleListMyActive().generateServiceMethodDefinition());
				this.serviceimpl.addMethod(omtm.getOracleListMyActive().generateServiceImplMethod());
				this.dao.addMethod(omtm.getOracleListMyActive().generateDaoMethodDefinition());
				this.daoimpl.addMethod(omtm.getOracleListMyActive().generateDaoImplMethod());
				this.mybatisOracleDaoXmlDecorator.addResultMap(omtm.getSlave());
				this.mybatisOracleDaoXmlDecorator.addDaoXmlMethod(omtm.getOracleListMyActive().generateDaoImplMethod());
				this.controller.addMethod(omtm.getOracleListMyActive().generateControllerMethod());

				this.service.addMethod(omtm.getOracleListMyAvailableActive().generateServiceMethodDefinition());
				this.serviceimpl.addMethod(omtm.getOracleListMyAvailableActive().generateServiceImplMethod());
				this.dao.addMethod(omtm.getOracleListMyAvailableActive().generateDaoMethodDefinition());
				this.daoimpl.addMethod(omtm.getOracleListMyAvailableActive().generateDaoImplMethod());
				//this.mybatisOracleDaoXmlDecorator.addDaoXmlMethod(omtm.getOracleListMyAvailableActive().generateDaoImplMethod());
				this.controller.addMethod(omtm.getOracleListMyAvailableActive().generateControllerMethod());
				//omtm.getSlave().decorateCompareTo();
				
				Service slaveService = new Service();
				slaveService.setDomain(omtm.getSlave());
				slaveService.addAnnotation("Autowired");
				slaveService.setStandardName(omtm.getSlave().getCapFirstDomainName() + "Service");
				
				Method slaveServiceSetter = NamedUtilMethodGenerator.generateSetter(omtm.getSlave().getLowerFirstDomainName()+"Service",
						new Type(omtm.getSlave().getCapFirstDomainName() + "Service",mtm.getSlave().getPackageToken()+"."+mtm.getSlave().getServiceSuffix()+"."+mtm.getSlave().getCapFirstDomainName() + "Service"));
				this.serviceimpl.addMethod(slaveServiceSetter);
				this.serviceimpl.addOtherService(slaveService);
			}
		}
	}
	
	public void generatePrismFromDomainWithDeniedFields(Boolean ignoreWarning,Set<Field> deniedFields) throws ValidateException, Exception {
		if (this.domain != null) {
			if (this.getPackageToken() != null) {
				this.domain.setPackageToken(packageToken);
			}
			
			this.domain.decorateCompareTo();

			this.dao = new Dao();
			this.dao.setDomain(this.domain);
			this.dao.setPackageToken(this.domain.getPackageToken());
			this.daoimpl = new DaoImpl();
			this.daoimpl.setPackageToken(this.domain.getPackageToken());
			this.daoimpl.setDomain(this.domain);
			this.daoimpl.setDao(this.dao);

			this.service = new Service();
			this.service.setDomain(this.domain);
			this.service.setPackageToken(this.domain.getPackageToken());
			this.serviceimpl = new ServiceImpl(this.domain);
			this.serviceimpl.setPackageToken(this.domain.getPackageToken());
			this.serviceimpl.getDao().addAnnotation("Autowired");
			Method daoSetter = NamedUtilMethodGenerator.generateSetter("dao",
					new Type(this.domain.getCapFirstDomainName() + "Dao"));
			this.serviceimpl.addMethod(daoSetter);
			this.serviceimpl.addClassImports("org.springframework.beans.factory.annotation.Autowired");
			this.serviceimpl.setDomain(this.domain);
			this.serviceimpl.setService(this.service);

			ListAll listAll = new ListAll(this.domain);	
			listAll.setDeniedFields(deniedFields);
			listAll.setDbType("oracle");
			
			Verb update = this.domain.hasDomainId() ?new Update(this.domain):null;
			Verb delete = this.domain.hasDomainId() ?new Delete(this.domain):null;
			Add add = this.domain.hasDomainId() ?new Add(this.domain):null;
			add.setDbType("oracle");
			update.setDeniedFields(deniedFields);
			Verb softdelete = this.domain.hasDomainId() && this.domain.hasActiveField() ?new SoftDelete(this.domain):null;
			FindById findbyid = this.domain.hasDomainId() ? new FindById(this.domain):null;
			findbyid.setDeniedFields(deniedFields);
			findbyid.setDbType("oracle");
			FindByName findbyname = this.domain.hasDomainName() ? new FindByName(this.domain):null;
			findbyname.setDeniedFields(deniedFields);
			findbyname.setDbType("oracle");
			ListActive listactive = this.domain.hasActiveField()?new ListActive(this.domain):null;
			listactive.setDeniedFields(deniedFields);
			listactive.setDbType("oracle");
			Verb deleteAll = this.domain.hasDomainId() ?new DeleteAll(this.domain):null;
			Verb softDeleteAll = this.domain.hasDomainId() && this.domain.hasActiveField() ?new SoftDeleteAll(this.domain):null;
			Verb toggle = this.domain.hasDomainId() && this.domain.hasActiveField() ?new Toggle(this.domain):null;
			Verb toggleOne = this.domain.hasDomainId() && this.domain.hasActiveField() ?new ToggleOne(this.domain):null;
			SearchByFieldsByPage searchByFieldsByPage = new SearchByFieldsByPage(this.domain);
			searchByFieldsByPage.setDeniedFields(deniedFields);
			searchByFieldsByPage.setDbType("oracle");
			Verb activate = this.domain.hasDomainId() && this.domain.hasActiveField() ?new Activate(this.domain):null;
			Verb activateAll = this.domain.hasDomainId() && this.domain.hasActiveField() ?new ActivateAll(this.domain):null;
			Verb export = new Export(this.domain);
			export.setDeniedFields(deniedFields);
			Verb exportPDF = new ExportPDF(this.domain);
			exportPDF.setDeniedFields(deniedFields);
			Verb exportWord = new ExportWord(this.domain);
			exportWord.setDeniedFields(deniedFields);
			Verb exportPPT = new ExportPPT(this.domain);
			exportPPT.setDeniedFields(deniedFields);
			SearchByFields searchByFields = new SearchByFields(this.domain);
			searchByFields.setDeniedFields(deniedFields);
			searchByFields.setDbType("oracle");
			Verb filterExcel = new FilterExcel(this.domain);
			filterExcel.setDeniedFields(deniedFields);
			Verb filterPDF = new FilterPDF(this.domain);
			filterPDF.setDeniedFields(deniedFields);
			Verb filterWord = new FilterWord(this.domain);
			filterWord.setDeniedFields(deniedFields);
			Verb filterPPT = new FilterPPT(this.domain);
			filterPPT.setDeniedFields(deniedFields);
			Verb clone	= this.domain.hasDomainId() ?new Clone(this.domain):null;
			Verb findFullInfoById = this.domain.hasDomainId() ?new FindFullInfoById(this.domain):null;
			Verb searchIndexedNamesByShortName = this.domain.hasDomainId() ?new SearchIndexedNamesByShortName(this.domain):null;
			Verb cloneAll = this.domain.hasDomainId()  ?new CloneAll(this.domain):null;
			Verb checkAcces = new CheckAccess(this.domain);

			CountSearchByFieldsRecords countSearch = new CountSearchByFieldsRecords(this.domain);
			countSearch.setDeniedFields(deniedFields);
			countSearch.setDbType("oracle");
			CountActiveRecords countActiveRecords = this.domain.hasDomainId() && this.domain.hasActiveField() ? new CountActiveRecords(this.domain):null;

			for (Field f:this.domain.getPlainFields()) {
				if (f.getFieldType().equalsIgnoreCase("image")) {
					domianFieldVerbs.add(new AddUploadDomainField(this.domain,f));
					domianFieldVerbs.add(new UpdateUploadDomainField(this.domain,f));
				}
			}
			
			this.addVerb(listAll);
			this.addVerb(update);
			this.addVerb(delete);
			this.addVerb(add);
			this.addVerb(softdelete);
			this.addVerb(findbyid);
			this.addVerb(findbyname);
			this.addVerb(listactive);
			this.addVerb(deleteAll);
			this.addVerb(softDeleteAll);
			this.addVerb(toggle);
			this.addVerb(toggleOne);
			this.addVerb(searchByFieldsByPage);
			this.addVerb(activate);
			this.addVerb(activateAll);
			this.addVerb(export);
			this.addVerb(exportPDF);
			this.addVerb(exportWord);
			this.addVerb(searchByFields);
			this.addVerb(filterExcel);
			this.addVerb(filterPDF);
			this.addVerb(filterWord);
			this.addVerb(clone);
			this.addVerb(findFullInfoById);
			this.addVerb(searchIndexedNamesByShortName);
			this.addVerb(cloneAll);
			this.addVerb(checkAcces);

			if (countSearch !=null) this.noControllerVerbs.add(countSearch);
			if (countActiveRecords !=null) this.noControllerVerbs.add(countActiveRecords);
			this.controller = new SpringMVCController(this.verbs, this.domain,ignoreWarning);
			this.controller.setPackageToken(this.packageToken);

			for (Verb v : this.verbs) {
				v.setDomain(domain);
				service.addMethod(v.generateServiceMethodDefinition());
				serviceimpl.addMethod(v.generateServiceImplMethod());
				dao.addMethod(v.generateDaoMethodDefinition());
				daoimpl.addMethod(v.generateDaoImplMethod());
				controller.addMethod(v.generateControllerMethod());
			}

			for (NoControllerVerb nVerb : this.noControllerVerbs) {
				nVerb.setDomain(domain);
				service.addMethod(nVerb.generateServiceMethodDefinition());
				serviceimpl.addMethod(nVerb.generateServiceImplMethod());
				dao.addMethod(nVerb.generateDaoMethodDefinition());
				daoimpl.addMethod(nVerb.generateDaoImplMethod());
			}

			for (DaoOnlyVerb oVerb : this.daoOnlyVerbs) {
				oVerb.setDomain(domain);
				dao.addMethod(oVerb.generateDaoMethodDefinition());
				daoimpl.addMethod(oVerb.generateDaoImplMethod());
			}
			
			for (DomainFieldVerb dfv:domianFieldVerbs) {
				this.controller.addMethod(dfv.generateControllerMethod());
			}

			this.mybatisOracleDaoXmlDecorator = new MybatisOracleDaoXmlDecorator();
			this.mybatisOracleDaoXmlDecorator.setDomain(this.getDomain());
			Set<Domain> resultMaps = new TreeSet<Domain>();
			resultMaps.add(this.domain);
			this.mybatisOracleDaoXmlDecorator.setResultMaps(resultMaps);
			Set<Method> daoimplMethods = new TreeSet<Method>();
			for (Verb vb : this.verbs) {
				if (vb!=null && vb.generateDaoImplMethod()!=null){
					daoimplMethods.add(vb.generateDaoImplMethod());
				}
			}
			for (DaoOnlyVerb dovb : this.daoOnlyVerbs) {
				if (dovb!=null && dovb.generateDaoImplMethod()!=null){
					daoimplMethods.add(dovb.generateDaoImplMethod());
				}
			}
			for (NoControllerVerb ncvb : this.noControllerVerbs) {
				if (ncvb!=null && ncvb.generateDaoImplMethod()!=null){
					daoimplMethods.add(ncvb.generateDaoImplMethod());
				}
			}
			this.mybatisOracleDaoXmlDecorator.setDaoXmlMethods(daoimplMethods);

			OracleEasyUIGridPagePI easyui = new OracleEasyUIGridPagePI(this.domain);
			easyui.setTechnicalStack(this.technicalStack);
			easyui.setTitles(this.title,this.subTitle, this.footer);
			this.addPage(easyui);

			if (this.domain.getManyToManies() != null && this.domain.getManyToManies().size() > 0) {
				this.setManyToManies(new TreeSet<>());
				for (ManyToMany mtm : this.domain.getManyToManies()) {
					String slaveName = mtm.getManyToManySalveName();
					String masterName = this.domain.getStandardName();
					if (setContainsDomain(this.projectDomains, masterName)
							&& setContainsDomain(this.projectDomains, slaveName)) {
						
						Domain myslave = (Domain)lookupDoaminInSet(this.projectDomains, slaveName).deepClone();
						if (!StringUtil.isBlank(mtm.getSlaveAlias())){
							myslave.setAlias(mtm.getSlaveAlias());
							myslave.setAliasLabel(mtm.getSlaveAliasLabel());
						}
						OracleManyToMany mymtm = new OracleManyToMany(lookupDoaminInSet(this.projectDomains, masterName),
								myslave,mtm.getMasterValue(),mtm.getValues());	
						mymtm.setSlaveAlias(myslave.getAlias());
						EasyUIMtmPI eumpt = mymtm.getEuPI();
						eumpt.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
						eumpt.setTechnicalStack(this.getTechnicalStack());
						mymtm.setEuPI(eumpt);
						this.manyToManies.add(mymtm);
					} else {
						ValidateInfo validateInfo = new ValidateInfo();
						validateInfo.addCompileError("棱柱" + this.getText() + "多对多设置有误。");
						ValidateException em = new ValidateException(validateInfo);
						throw em;
					}
				}
			}
			for (ManyToMany mtm : this.manyToManies) {
				OracleManyToMany omtm = (OracleManyToMany) mtm;
				omtm.setTitle(this.title);
				omtm.setSubTitle(this.subTitle);
				omtm.setFooter(this.footer);
				omtm.setCrossOrigin(this.crossOrigin);
				this.service.addMethod(omtm.getOracleAssign().generateServiceMethodDefinition());
				this.serviceimpl.addMethod(omtm.getOracleAssign().generateServiceImplMethod());
				this.dao.addMethod(omtm.getOracleAssign().generateDaoMethodDefinition());
				this.daoimpl.addMethod(omtm.getOracleAssign().generateDaoImplMethod());
				this.mybatisOracleDaoXmlDecorator.addDaoXmlMethod(omtm.getOracleAssign().generateDaoImplMethod());
				this.controller.addMethod(omtm.getOracleAssign().generateControllerMethod());

				this.service.addMethod(omtm.getOracleRevoke().generateServiceMethodDefinition());
				this.serviceimpl.addMethod(omtm.getOracleRevoke().generateServiceImplMethod());
				this.dao.addMethod(omtm.getOracleRevoke().generateDaoMethodDefinition());
				this.daoimpl.addMethod(omtm.getOracleRevoke().generateDaoImplMethod());
				this.mybatisOracleDaoXmlDecorator.addDaoXmlMethod(omtm.getOracleRevoke().generateDaoImplMethod());
				this.controller.addMethod(omtm.getOracleRevoke().generateControllerMethod());

				this.service.addMethod(omtm.getOracleListMyActive().generateServiceMethodDefinition());
				this.serviceimpl.addMethod(omtm.getOracleListMyActive().generateServiceImplMethod());
				this.dao.addMethod(omtm.getOracleListMyActive().generateDaoMethodDefinition());
				this.daoimpl.addMethod(omtm.getOracleListMyActive().generateDaoImplMethod());
				this.mybatisOracleDaoXmlDecorator.addResultMap(omtm.getSlave());
				this.mybatisOracleDaoXmlDecorator.addDaoXmlMethod(omtm.getOracleListMyActive().generateDaoImplMethod());
				this.controller.addMethod(omtm.getOracleListMyActive().generateControllerMethod());

				this.service.addMethod(omtm.getOracleListMyAvailableActive().generateServiceMethodDefinition());
				this.serviceimpl.addMethod(omtm.getOracleListMyAvailableActive().generateServiceImplMethod());
				this.dao.addMethod(omtm.getOracleListMyAvailableActive().generateDaoMethodDefinition());
				this.daoimpl.addMethod(omtm.getOracleListMyAvailableActive().generateDaoImplMethod());
				//this.mybatisOracleDaoXmlDecorator.addDaoXmlMethod(omtm.getOracleListMyAvailableActive().generateDaoImplMethod());
				this.controller.addMethod(omtm.getOracleListMyAvailableActive().generateControllerMethod());
				//omtm.getSlave().decorateCompareTo();
				
				Service slaveService = new Service();
				slaveService.setDomain(omtm.getSlave());
				slaveService.addAnnotation("Autowired");
				slaveService.setStandardName(omtm.getSlave().getCapFirstDomainName() + "Service");
				
				Method slaveServiceSetter = NamedUtilMethodGenerator.generateSetter(omtm.getSlave().getLowerFirstDomainName()+"Service",
						new Type(omtm.getSlave().getCapFirstDomainName() + "Service",mtm.getSlave().getPackageToken()+"."+mtm.getSlave().getServiceSuffix()+"."+mtm.getSlave().getCapFirstDomainName() + "Service"));
				this.serviceimpl.addMethod(slaveServiceSetter);
				this.serviceimpl.addOtherService(slaveService);
			}
		}
	}
	
	public void removeNoControllerVerb(NoControllerVerb nv) throws Exception{
		if (nv!=null) {
			this.noControllerVerbs.remove(nv);
			service.removeMethod(nv.generateServiceMethodDefinition());
			serviceimpl.removeMethod(nv.generateServiceImplMethod());
			dao.removeMethod(nv.generateDaoMethodDefinition());
			daoimpl.removeMethod(nv.generateDaoImplMethod());
			if (getMybatisOracleDaoXmlDecorator()!=null) getMybatisOracleDaoXmlDecorator().removeDaoXmlMethod(nv.generateDaoImplMethod());
		}
	}

	public MybatisOracleDaoXmlDecorator getMybatisOracleDaoXmlDecorator() {
		return mybatisOracleDaoXmlDecorator;
	}

	public void setMybatisOracleDaoXmlDecorator(MybatisOracleDaoXmlDecorator mybatisOracleDaoXmlDecorator) {
		this.mybatisOracleDaoXmlDecorator = mybatisOracleDaoXmlDecorator;
	}
}
